<template>
    <div class="content">
        <!--
            从vuex里获取内容并动态渲染到组件里的方式：
            1.在v-bind里直接写$store.state.xxx (字符串只能用这个方式)。
            2.在computed(计算属性)里声明一个方法，方法里 return this.$store.state (字符串只能用这个方式)。
            3.数组、Map、Set等数据结构，要用push、set、add等方法才能触发动态渲染，直接赋值是不行的。

            参考学习文章：https://www.jb51.net/article/199749.htm
       -->
        <el-tabs v-model="getNavBarActionName" type="card" closable @tab-click="handleClick" @tab-remove="removeTab">
            <el-tab-pane
                v-for="item in navBarList"
                :key="item.split('-')[0]"
                :label="item.split('-')[0]"
                :name="item"
            >
                {{item.split('-')[0]}}
            </el-tab-pane>
        </el-tabs>


        <keep-alive :include="$store.state.navBar.keepAliveList"><!-- 通过vuex动态设置keep-alive缓存(include接收一个数组，里面是组件的name) -->
            <router-view></router-view>
        </keep-alive>
        
    </div>
</template>

<script>
export default{
    name:'home-content',
    data(){
        return{
            navBarList:this.$store.state.navBar.navBarList //把导航菜单以数组的形式存储起来,放入vuex里面。   
            /*
            只有数组、map结构可以直接这样赋值，字符串类型是不行的，组件无法动态感应到字符串类型的变化。
             */         
        }
    },
    methods:{
        handleClick(tab, event){
            // console.log(tab.name);
            //1.把导航菜单的活动项名称，设置到vuex的navBarActionName字符串变量里,用于同步设置navbar里的活动项。
            this.$store.dispatch('setNavBarActionName',tab.name)

            //2.跳转到点击的导航菜单项对应的子路由，渲染对应的子组件
            //this.$router.push({path:'/home/'+tab.name.split('-')[1]});
            //这里不需要了，在navbar组件里通过watch监听导航菜单活动项的改变，进行路由跳转。
        },
        removeTab(targetName){
            // console.log(targetName);

            let activeName = this.getNavBarActionName;
            let navBarList = this.navBarList;
            const lengthNumber = navBarList.length;

            //步骤1：如果删除的菜单项是活动项，则把vuex中活动项名称设置为它的右边的菜单项(优先)或左边的菜单项(这里照抄的elementui官网的例子)
            if(activeName === targetName){
                navBarList.forEach((tab,index) => {
                    if (tab === targetName) {
                        let nextTab = navBarList[index + 1] || navBarList[index - 1] || navBarList[index];//最后这个navBarList[index]是考虑到只有一个导航菜单项的时候。
                        if (nextTab) {
                            activeName = nextTab;
                        }
                    }
                });
                this.$store.dispatch('setNavBarActionName',activeName);
            }


            //步骤2：把vuex中导航菜单中对应项删除(只剩一个的时候不删除)
            if(lengthNumber>1){
                this.$store.dispatch('removeNavBarList',targetName);
            }
            


            //步骤3：把vuex中keep-alive的允许缓存的数组里的对应项删除(只剩一个的时候不删除)
            if(lengthNumber>1){
                this.$store.dispatch('removeKeepAliveList','content-'+(targetName.split('-')[1]));
            }
            

            //步骤4：跳转到活动导航菜单项对应的子路由，渲染对应的子组件
            //this.$router.push({path:'/home/'+targetName.split('-')[1]});
            //这里不需要了，在navbar组件里通过watch监听导航菜单活动项的改变，进行路由跳转。
        }
    },
    computed:{
        getNavBarActionName:{
            /*
            从vuex里获取导航菜单的活动项目名称。
            注意：在v-model中使用computed时，computed必须要设置get和set方法，否则控制台会出现warn。
            */
            get(){
                return this.$store.state.navBar.navBarActionName;
            },
            set(value){ //这个set虽然没有用，但是需要写上，否则控制台会提示错误，因为这个计算属性用在v-model做了双向绑定。

            }
            
        }
    }
}
</script>

<style scoped>

/*
下面两个样式的作用：
父元素通过加大内边距(padding)，子元素通过内折外边距(margin),达到预留出100%父级空间的作用。
目的是方便另一个子元素直接占用100%的父级空间。
参考文章：https://blog.csdn.net/weixin_43331146/article/details/86560506
 */
.content{
    padding: 42px 0 0;
}
.el-tabs{
    margin: -42px 0 0;
}
/** ***************************************************************** */

.el-tabs>>>.el-tabs__content{ /*取消掉组件自带的一些效果*/
  display: none;
}

.el-tabs>>>.el-tabs__header{ /* 取消组件自带的一些效果 */
    margin-bottom: 0;
}

.el-tabs>>>.el-tabs__item{
    width: 110px; /* 组件默认根据文字内容来撑起宽度的，我把宽度设置为固定的，为了统一美观 */
    text-align: center; /* 组件默认字体靠左，我设置为居中 */
    color: #E4E7ED; /* 设置字体颜色(非活动) */
}

.el-tabs>>>.el-tabs__item.is-active{ /* 设置活动标签的字体颜色和大小 */
    color: #58c2f7;
    font-size: 16px;
    font-weight: 700;
}
</style>